package com.lmind.captcha;

import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

public class SimpleCaptchaVerifyService implements ICaptchaVerifyService,
		Runnable {

	private ICaptchaBuilder builder;

	private Map<String, CaptchaVerify> captchaMap = new ConcurrentHashMap<String, CaptchaVerify>();

	private ScheduledExecutorService executor;

	private long period = 60000 * 5;

	private long liveTime = 60000 * 5;

	private volatile ScheduledFuture<?> scheduledFuture;

	private volatile boolean started = false;
	
	private AtomicLong completed = new AtomicLong();

	public SimpleCaptchaVerifyService() {

	}

	public ICaptchaBuilder getBuilder() {
		return builder;
	}

	/**
	 * 设置ICaptchaBuilder的实例
	 * 
	 * @param builder
	 */
	public void setBuilder(ICaptchaBuilder builder) {
		this.builder = builder;
	}

	public ScheduledExecutorService getExecutor() {
		return executor;
	}

	/**
	 * 设置执行调度服务的线程池,它被用来执行验证码超时清理任务本
	 * 
	 * @param executor
	 */
	public void setExecutor(ScheduledExecutorService executor) {
		this.executor = executor;
	}

	public long getPeriod() {
		return period;
	}

	/**
	 * 验证码超时清理任务的时间间隔，单位毫秒
	 * 
	 * @param period
	 */
	public void setPeriod(long period) {
		this.period = period;
	}

	public long getLiveTime() {
		return liveTime;
	}

	/**
	 * 每个验证码的有效期
	 * 
	 * @param liveTime
	 */
	public void setLiveTime(long liveTime) {
		this.liveTime = liveTime;
	}
	

	public long getCompleted() {
		return completed.get();
	}

	/**
	 * 启动本服务
	 */
	public synchronized void start() {
		scheduledFuture = executor.scheduleAtFixedRate(this, 0, period,
				TimeUnit.MILLISECONDS);
		started = true;
	}

	/**
	 * 停止本服务
	 */
	public synchronized void stop(boolean mayInterruptIfRunning) {
		started = false;
		scheduledFuture.cancel(mayInterruptIfRunning);
		scheduledFuture = null;
	}

	@Override
	public CaptchaVerify getCaptcha() {

		if (!started) {
			throw new CaptchaException("SimpleCaptchaVerifyService尚未启动");
		}

		ICaptcha captcha = builder.build();

		CaptchaVerify v = new CaptchaVerify(UUID.randomUUID().toString(),
				captcha.getAnswer(), captcha.getImage(), new Date().getTime());
		captchaMap.put(v.getToken(), v);

		return v;

	}

	@Override
	public boolean verify(String token, String answer) {

		if (!started) {
			throw new CaptchaException("SimpleCaptchaVerifyService尚未启动");
		}

		CaptchaVerify info = captchaMap.get(token);

		if (info == null
				|| info.getTimestamp() + liveTime < new Date().getTime())
			return false;
		if (!info.getAnswer().equals(answer))
			return false;

		return true;
	}

	@Override
	public void run() {

		// 定时清理过期信息
		Date now = new Date();
		Iterator<Entry<String, CaptchaVerify>> iter = captchaMap.entrySet()
				.iterator();
		while (iter.hasNext()) {
			CaptchaVerify v = iter.next().getValue();
			if (v.getTimestamp() + liveTime < now
					.getTime()) {
				iter.remove();
				completed.addAndGet(1);
			}
		}

	}

}
